import {
    watch,
    ref,
    shallowRef,
    reactive,
    computed,
    getCurrentInstance,
    inject,
    toRef,
} from "vue"
import { resetFormData, transFormData } from "@gd-accbuild-ui/gd-ui/utils";
import { getCurEventDynmicMetaAttrSettings } from "@gd-accbuild-core/hooks/useGetCurUiTemplateInfo";
import { globalConfig } from "@gd-accbuild-core/config";
import {
    isSuccessReqBackend,
    getBackendData,
    getBackendDataItems,
    cloneDeep,
} from "@gd-accbuild-core/config/utils";
import gdLoadingService from "@gd-accbuild-ui/gd-ui/gd-service/gd-loading-service/gd-loading-service"

const updatePaginationConfig = ({ valOrMember, member, val, props }) => {
    if (
        typeof valOrMember === "object" &&
        valOrMember.hasOwnProperty("pageObj")
    ) {
        props.tableCommonAttr.paginationConfig = {};
        props.tableCommonAttr.paginationConfig.pageObj = valOrMember.pageObj;
    } else if (
        typeof valOrMember === "string" &&
        typeof member === "string" &&
        typeof val === "number"
    ) {
        props.tableCommonAttr.paginationConfig = {};
        props.tableCommonAttr.paginationConfig[valOrMember][member] = val;
    }
};
///////////////////////
/**
 * 当需要临时状态时(如:编辑状态),设置单元格的强制配置属性
 */
const setCellForceMetaConfigMapping = (newLineRowKey, props, metaItemList) => {
    const dialogFormItemDynmicConfigList = props.dialogFormItemDynmicConfigList;
    metaItemList.value.forEach((el) => {
        const dynmicConfig = dialogFormItemDynmicConfigList.find(
            (conf) => conf.key === el.key
        );
        props.cellForceMetaConfigMapping[`${newLineRowKey};${el.key}`] = {
            staticConfig: cloneDeep(el),
            dynmicConfig: cloneDeep(dynmicConfig),
        };
    });
};
/**
 * 取消单元格临时状态,恢复之前状态。(如:编辑取消)
 */
const resetCellForceMetaConfigMapping = (newLineRowKey, props) => {
    Object.keys(props.cellForceMetaConfigMapping).forEach((key) => {
        if (key.startsWith(`${newLineRowKey};`)) {
            delete props.cellForceMetaConfigMapping[key];
        }
    });
};


const callback = (err) => {
    throw err;
};
const excludeLoadingStrategys = ["buildInBatchDeleteBtn", "buildInRowDeleteBtn", "buildInContainerCancelBtn", "buildInAddBtn", "buildInAddChildIntoCurBtn"]
const doEventstrategy = async ({
    newOperationEventParams,
    oldOperationEventParams,
}, props, vm, isShowContainer, commonAttr, metaItemList, formData, historyAllOrgRowData, historyAllOperationEventParams, containerEventFromConfig, isInlineEditable, fillFieldsIntoAddForm, tableOperationMethods, crudServiceVmTemplateConfig) => {

    const curRowIdx = newOperationEventParams.rowIdx;
    const curRowData = newOperationEventParams.rowData;
    const eventstrategyName = newOperationEventParams.metaKey;
    const curContainerOperationEventParams =
        historyAllOperationEventParams[`${curRowIdx}`];
    const submitEventstrategyName = curContainerOperationEventParams?.metaKey;
    const containerStyle = newOperationEventParams.metaItem?.containerAttr?.containerStyle;
    const vmCode = newOperationEventParams.metaItem.vmCode;
    const submitVmCode = curContainerOperationEventParams?.metaItem?.vmCode;

    const keyField = vm.$attrs["key-field"];
    const parentKeyField = vm.$attrs["parent-key-field"];
    const curPickedRowIds = vm.$attrs["cur-picked-row-ids"];
    const tableBodyData = vm.$attrs["table-body-data"];
    const flattenTableBodyData = vm.$attrs["flatten-table-body-data"];
    const isLazyTable = props.tableCommonAttr?.treeTableConfig?.lazy ?? false;

    let isReloadTableDefault = false;
    //设置容器显示隐藏
    let willIsShowContainer = isShowContainer.value;
    if (
        ["buildInContainerCancelBtn", "buildInContainerSubmitBtn"].includes(
            eventstrategyName
        )
    ) {
        willIsShowContainer = false;
        ///////
        containerEventFromConfig.rowIdx = null;
        containerEventFromConfig.rowData = null;
    } else if (containerStyle && typeof containerStyle === "string") {
        willIsShowContainer = true;
        ///////
        containerEventFromConfig.rowIdx = curRowIdx;
        containerEventFromConfig.rowData = curRowData;
    }

    //点击事件前拦截
    let beforeClickFunc = ((configObj) => { });
    if (newOperationEventParams.metaItem.hasOwnProperty("beforeClickFunc")) {
        if (typeof newOperationEventParams.metaItem["beforeClickFunc"] === "string") {
            beforeClickFunc = new Function("configObj", newOperationEventParams.metaItem.beforeClickFunc)
        } else if (typeof newOperationEventParams.metaItem["beforeClickFunc"] === "function") {
            beforeClickFunc = newOperationEventParams.metaItem.beforeClickFunc
        }
    }

    const overrideEventFuncParams = {
        allBtnsEmitFormItemMetaConfig: props.allBtnsEmitFormItemMetaConfig,
        getCurEventDynmicMetaAttrSettings,
        resetFormData,
        transFormData,
        setCellForceMetaConfigMapping,
        newOperationEventParams,
        fillFieldsIntoAddForm,
        isPassThrough: false,
        //////
        historyAllOrgRowData,
        willIsShowContainer,
        isInlineEditable: isInlineEditable.value,
        props,
        curRowIdx,
        curRowData,
        eventstrategyName,
        keyField,
        parentKeyField,
        crudServiceVmTemplateConfig,
        submitVmCode,
        vmCode,
        tableBodyData: tableBodyData,
        flattenTableBodyData: flattenTableBodyData,
        formData: formData.value,
        formDataProxy: formData,
        metaItemList: metaItemList.value,
        metaItemListProxy: metaItemList,
        tableOperationMethods,
    }

    const events = {
        //toolbar按钮
        buildInAddBtn: async () => {
            metaItemList.value =
                props.allBtnsEmitFormItemMetaConfig.buildInAddOrEditBtn.map((el) =>
                    getCurEventDynmicMetaAttrSettings(el, eventstrategyName)
                );
            resetFormData(formData.value, metaItemList.value);
            if (formData.value.hasOwnProperty(parentKeyField)) {
                formData.value[parentKeyField] = null;
            }
            Object.keys(fillFieldsIntoAddForm).forEach((key) => {
                formData.value[key] = fillFieldsIntoAddForm[key];
            });
            if (isInlineEditable.value) {
                willIsShowContainer = false;
                const newLineRowKey = curRowData[keyField];
                tableOperationMethods.insertAt({
                    ...formData.value,
                    [keyField]: newLineRowKey,
                });
                /////
                tableOperationMethods.setActiveRow(tableBodyData[curRowIdx]);
                setCellForceMetaConfigMapping(newLineRowKey, props, metaItemList);
                Object.keys(props.cellForceMetaConfigMapping).forEach(key => {
                    getCurEventDynmicMetaAttrSettings(props.cellForceMetaConfigMapping[key], eventstrategyName)
                })
            }
        },
        buildInBatchDeleteBtn: async () => { },
        //表格操作按钮
        buildInAddChildIntoCurBtn: async () => {
            metaItemList.value =
                props.allBtnsEmitFormItemMetaConfig.buildInAddOrEditBtn.map((el) =>
                    getCurEventDynmicMetaAttrSettings(el, "buildInAddBtn")
                );
            resetFormData(formData.value, metaItemList.value, {
                [parentKeyField]: newOperationEventParams.rowData[keyField],
            });
        },
        buildInRowDeleteBtn: async () => { },
        buildInEditBtn: async () => {
            metaItemList.value =
                props.allBtnsEmitFormItemMetaConfig.buildInAddOrEditBtn.map((el) =>
                    getCurEventDynmicMetaAttrSettings(el, eventstrategyName)
                );
            if (isInlineEditable.value) {
                willIsShowContainer = false;
                tableOperationMethods.setEditRow(newOperationEventParams.rowData);
                historyAllOrgRowData[`${curRowIdx}`] = cloneDeep(
                    newOperationEventParams.rowData
                );
                const newLineRowKey = newOperationEventParams.rowData[keyField];
                setCellForceMetaConfigMapping(newLineRowKey, props, metaItemList);
                Object.keys(props.cellForceMetaConfigMapping).forEach(key => {
                    getCurEventDynmicMetaAttrSettings(props.cellForceMetaConfigMapping[key], eventstrategyName)
                })
                return;
            }
            const curRowKeyFieldVal = newOperationEventParams.rowData[keyField];
            const params = { [keyField]: curRowKeyFieldVal };
            const res = await globalConfig.get({
                moduleCode: crudServiceVmTemplateConfig.table.moduleCode,
                vmCode,
                params,
                vmTemplateConfig: crudServiceVmTemplateConfig.table
            });
            if (isSuccessReqBackend(res)) {
                formData.value = getBackendData(res);
            }
        },
        //容器内置按钮
        buildInContainerCancelBtn: async () => {
            if (isInlineEditable.value) {
                willIsShowContainer = false;
                if (tableBodyData[curRowIdx][keyField].startsWith("_gd_id_")) {
                    tableOperationMethods.remove([tableBodyData[curRowIdx]]);
                }
                const newLineRowKey = newOperationEventParams.rowData[keyField];
                resetCellForceMetaConfigMapping(newLineRowKey, props);
                return;
            }
        },
        buildInContainerSubmitBtn: async () => {
            const submitEventStrategy = {
                buildInAddBtn: async () => {
                    const addSubmitData = isInlineEditable.value
                        ? transFormData(cloneDeep(curRowData), metaItemList.value)
                        : transFormData(cloneDeep(formData.value), metaItemList.value);

                    delete addSubmitData["_X_ROW_CHILD"]; //删除vxe-table引入的额外字段
                    const newLineRowKey = addSubmitData[keyField];
                    resetCellForceMetaConfigMapping(newLineRowKey, props);

                    delete addSubmitData[keyField];
                    const res = await globalConfig.save({
                        moduleCode: crudServiceVmTemplateConfig.table.moduleCode,
                        vmCode: submitVmCode,
                        data: addSubmitData,
                        vmTemplateConfig: crudServiceVmTemplateConfig.table
                    });
                    if (isSuccessReqBackend(res)) {
                        const data = getBackendData(res);
                        if (isInlineEditable.value) {
                            tableOperationMethods?.remove?.(curRowData);
                        }
                        tableOperationMethods?.insertAt?.(data, -1);
                    }
                },
                buildInAddChildIntoCurBtn: async () => {
                    const res = await globalConfig.save({
                        moduleCode: crudServiceVmTemplateConfig.table.moduleCode,
                        vmCode: submitVmCode,
                        data: transFormData(cloneDeep(formData.value), metaItemList.value),
                        vmTemplateConfig: crudServiceVmTemplateConfig.table
                    });
                    if (isSuccessReqBackend(res)) {
                        const data = getBackendData(res);

                        const matchedCurRowData = flattenTableBodyData.find(
                            (el) => el[keyField] === data[parentKeyField]
                        );
                        matchedCurRowData.hasChildren = true;
                        tableOperationMethods?.insertAt?.(data, -1);
                        // if (!isLazyTable) {
                        //     tableOperationMethods?.insertAt?.(data, -1);
                        // }
                    }
                },
                buildInBatchDeleteBtn: async () => {
                    const res = await globalConfig.deleteBatch({
                        moduleCode: crudServiceVmTemplateConfig.table.moduleCode,
                        vmCode: submitVmCode,
                        params: {
                            ids: curPickedRowIds,
                        },
                        vmTemplateConfig: crudServiceVmTemplateConfig.table
                    });
                    if (isSuccessReqBackend(res)) {
                        const delRows = curPickedRowIds.map((id) => {
                            return flattenTableBodyData.find((el) => el.id === id);
                        });
                        tableOperationMethods?.remove?.(delRows);
                    }
                },
                buildInRowDeleteBtn: async () => {
                    if (curRowData[keyField].startsWith("_gd_id_")) {
                        const delRow = tableBodyData.find(
                            (el) => el.id === curRowData[keyField]
                        );
                        tableOperationMethods?.remove?.(delRow);
                    } else {
                        const res = await globalConfig.deleteBatch({
                            moduleCode: crudServiceVmTemplateConfig.table.moduleCode,
                            vmCode: submitVmCode,
                            params: {
                                ids: [curRowData[keyField]],
                            },
                            vmTemplateConfig: crudServiceVmTemplateConfig.table
                        });
                        if (isSuccessReqBackend(res)) {
                            const delRow = tableBodyData.find(
                                (el) => el.id === curRowData[keyField]
                            );
                            tableOperationMethods?.remove?.(delRow);
                        }
                    }
                },
                buildInEditBtn: async () => {
                    const editSubmitData = isInlineEditable.value
                        ? transFormData(cloneDeep(curRowData), metaItemList.value)
                        : transFormData(cloneDeep(formData.value), metaItemList.value);
                    delete editSubmitData["_X_ROW_CHILD"]; //删除vxe-table引入的额外字段
                    const res = await globalConfig.update({
                        moduleCode: crudServiceVmTemplateConfig.table.moduleCode,
                        vmCode: submitVmCode,
                        data: editSubmitData,
                        vmTemplateConfig: crudServiceVmTemplateConfig.table
                    });
                    if (isSuccessReqBackend(res)) {
                        const data = getBackendData(res);
                        tableOperationMethods?.updateRowsData?.([data]);
                    }
                    const newLineRowKey = editSubmitData[keyField];
                    resetCellForceMetaConfigMapping(newLineRowKey, props);
                },
            };
            await submitEventStrategy[submitEventstrategyName]();
        },
    };

    let isPassBeforeClick = true;
    try {
        beforeClickFunc({
            curPickedRowIds,
            tableBodyData,
            callback,
        });
    } catch (e) {
        console.warn(e.message);
        isPassBeforeClick = false;
    }
    if (!isPassBeforeClick) {
        return;
    }


    const loadingInstance = !excludeLoadingStrategys.includes(eventstrategyName) ? gdLoadingService({ fullscreen: true }) : false

    const isOverrideBuildInContainerEmitEvent = crudServiceVmTemplateConfig.table?.strategys?.hasOwnProperty(eventstrategyName)
    const isOverrideBuildInContainerSubmitBtn = crudServiceVmTemplateConfig.table?.strategys?.[eventstrategyName]?.hasOwnProperty(submitEventstrategyName)
    let isOverrideStrategyExists = false;

    if (isOverrideBuildInContainerSubmitBtn) {
        let doExec = null
        if (typeof crudServiceVmTemplateConfig.table.strategys.buildInContainerSubmitBtn[submitEventstrategyName] === "function") {
            doExec = crudServiceVmTemplateConfig.table.strategys.buildInContainerSubmitBtn[submitEventstrategyName]
        } else if (typeof crudServiceVmTemplateConfig.table.strategys.buildInContainerSubmitBtn[submitEventstrategyName] === "string") {
            doExec = new Function("configObj", crudServiceVmTemplateConfig.table.strategys.buildInContainerSubmitBtn[submitEventstrategyName])
        }
        if (doExec) {
            isOverrideStrategyExists = true
            await doExec(overrideEventFuncParams)
        }
    } else if (isOverrideBuildInContainerEmitEvent) {
        let doExec = null
        if (typeof crudServiceVmTemplateConfig.table.strategys[eventstrategyName] === "function") {
            doExec = crudServiceVmTemplateConfig.table.strategys[eventstrategyName]
        } else if (typeof crudServiceVmTemplateConfig.table.strategys[eventstrategyName] === "string") {
            doExec = new Function("configObj", crudServiceVmTemplateConfig.table.strategys[eventstrategyName])
        }
        if (doExec) {
            isOverrideStrategyExists = true
            await doExec(overrideEventFuncParams)
        }
    }

    if ((!isOverrideStrategyExists && events.hasOwnProperty(eventstrategyName)) || (isOverrideStrategyExists && overrideEventFuncParams.isPassThrough)) {
        await events[eventstrategyName]();
    } else {
    }
    loadingInstance && loadingInstance.close()

    isShowContainer.value = isOverrideStrategyExists && !overrideEventFuncParams.isPassThrough ? overrideEventFuncParams.willIsShowContainer : willIsShowContainer;

    if (
        eventstrategyName === "buildInContainerSubmitBtn" &&
        (curContainerOperationEventParams.metaItem?.isReloadTable ??
            isReloadTableDefault)
    ) {
        //TODO:FIXME: 重载表格数据
        const paginationConfig = vm.$attrs["pagination-config"];
        const pageParams = !paginationConfig.isPaged
            ? { isPaged: true }
            : {
                pageNum: paginationConfig?.pageObj?.pageNum ?? 0,
                pageSize: paginationConfig?.pageObj?.pageSize ?? 0,
            };
        const queryParams = {};
        const res = await globalConfig.getList({
            moduleCode: crudServiceVmTemplateConfig.table.moduleCode,
            vmCode: crudServiceVmTemplateConfig.table.vmCode,
            params: {
                ...queryParams,
                ...pageParams,
            },
            vmTemplateConfig: crudServiceVmTemplateConfig.table
        });
        if (isSuccessReqBackend(res)) {
            const dataList = getBackendDataItems(res);
            tableOperationMethods?.updateRowsData?.(dataList);
            updatePaginationConfig({ valOrMember: "pageObj", member: "totalCount", val: 101, props }) //TODO:FIXME:
        }
    }
    if (
        ["buildInContainerSubmitBtn", "buildInContainerCancelBtn"].includes(
            eventstrategyName
        )
    ) {
        if (
            historyAllOperationEventParams.hasOwnProperty(
                `${props.operationEventParams.rowIdx}`
            )
        ) {
            delete historyAllOperationEventParams[
                `${props.operationEventParams.rowIdx}`
            ];
        }
        if (
            historyAllOrgRowData.hasOwnProperty(
                `${props.operationEventParams.rowIdx}`
            )
        ) {
            delete historyAllOrgRowData[`${props.operationEventParams.rowIdx}`];
        }
    }
};
export default (props) => {
    ////////////////
    const crudServiceVmTemplateConfig = inject(
        "crudServiceVmTemplateConfig",
        reactive({ table: {} })
    );
    ///////////////
    let cacheContainerAttr = {}
    const containerAttr = computed(() => {
        if (props.operationEventParams.metaKey === "buildInContainerSubmitBtn") {
            return cacheContainerAttr
        }
        cacheContainerAttr = props.operationEventParams?.metaItem?.containerAttr ?? {};
        return cacheContainerAttr
    });

    const { proxy: vm } = getCurrentInstance();
    const isInlineEditable = computed(() => {
        return props.tableCommonAttr?.editConfig?.editableStyle === "Inline";
    });
    const fillFieldsIntoAddForm = inject("fillFieldsIntoAddForm", reactive({}));

    const tableOperationMethods = inject("tableOperationMethods", reactive({}));

    const commonAttr = ref({});
    const metaItemList = ref([]);
    const formData = ref({});
    const isShowContainer = ref(false);
    const containerEventFromConfig = reactive({
        rowIdx: null,
        rowData: null,
        formData: null,
    });

    const historyAllOrgRowData = reactive({});
    const historyAllOperationEventParams = reactive({});
    watch(
        () => props.operationEventParams,
        (newVal, oldVal) => {
            if (
                !["buildInContainerCancelBtn", "buildInContainerSubmitBtn"].includes(
                    newVal.metaKey
                )
            ) {
                historyAllOperationEventParams[`${props.operationEventParams.rowIdx}`] =
                    props.operationEventParams;
            } else {
            }
            doEventstrategy({
                newOperationEventParams: newVal,
                oldOperationEventParams: oldVal,
            }, props, vm, isShowContainer, commonAttr, metaItemList, formData, historyAllOrgRowData, historyAllOperationEventParams, containerEventFromConfig, isInlineEditable, fillFieldsIntoAddForm, tableOperationMethods, crudServiceVmTemplateConfig);
        }
    );
    return { isShowContainer, containerAttr, containerEventFromConfig, commonAttr, metaItemList, formData, vmTemplateConfigRefVal: toRef(crudServiceVmTemplateConfig, "table") }
}